﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace MazeNet.Communication
{
    public abstract class PlayerBase
    {
        #region Properties
        public int Id { get { return _mID; } set { _mID = value; } }
        #endregion

        #region statische Member
        private static List<Point> _mInsertPositions;
        #endregion

        protected int _mID;
        public abstract MoveMessageType CalculateMove(AwaitMoveMessageType _uAwaitMoveMsg);

        /// <summary>
        /// statischer Konstruktor sorgt dafuer, dass InsertPositions
        /// besetzt werden
        /// </summary>
        static PlayerBase()
        {
            _mInsertPositions = new List<Point>();

            for (int i = 1; i < 6; i += 2)
            {
                _mInsertPositions.Add(new Point(i, 0));
                _mInsertPositions.Add(new Point(i, 6));
            }
        }

        /// <summary>
        /// Generiert alle 48 Möglichkeiten wie das Board nach dem Einfügen der Karte 
        /// aussehen kann.
        /// </summary>
        /// <param name="_uBoard">Das aktuelle Board, ohne shift.</param>
        /// <param name="_uShiftCard">Karte die eingefügt werden soll.</param>
        /// <returns></returns>
        protected static List<Move> GenerateMoves(boardType _uBoard)
        {
            List<Move> _lRet = new List<Move>();
            List<Point> _lPossibleInsertPositions;
            boardType _lCurrentBoard;

            //Insert Positions holen und verbotene entfernen
            _lPossibleInsertPositions = new List<Point>(_mInsertPositions);
            if (_uBoard.forbidden != null)
            {
                _lPossibleInsertPositions.RemoveAll(p => p.Equals(new Point(_uBoard.forbidden.col, _uBoard.forbidden.row)));
            }

            //Alle moves erstellen
            foreach (Point p in _lPossibleInsertPositions)
            {
                //In allen vier drehungen
                for (int i = 0; i < 4; ++i)
                {
                    //Karte drehen
                    _uBoard.shiftCard.TurnLeft();
                    //Feld klonen und karte einfuegen
                    _lCurrentBoard = new boardType(_uBoard);
                    _lCurrentBoard.Push(p, true);
                    //zu Ergebnismenge hinzfuegen
                    _lRet.Add(new Move(_lCurrentBoard, new cardType(_uBoard.shiftCard), p));
                }
            }

            //Rueckgabe
            return _lRet;
        }


    }
}
